package com.brycen.nio.buffer;

import java.nio.ByteBuffer;

public class ByteBufferStickyBag {

    /**
     * 演示ByteBuffer的黏包和半包问题
     *
     * 网络发送多条数据，数据中间使用\n分割，客户端发送如下三条信息
     * Hello,world\n
     * I'm Brycen\n
     * How are you?\n
     * 上面的三条信息，经过重新组合，服务端可能收到的是这样的（黏包、半包）
     * Hello,world\nI'm Brycen\nHo
     * w are you?\n
     * @param args
     */
    public static void main(String[] args) {
        ByteBuffer byteBuffer = ByteBuffer.allocate(1024);
        //模拟第一次接受信息
        byteBuffer.put("Hello,world\nI'm Brycen\nHo".getBytes());
        split(byteBuffer);
        //模拟第二次接受信息
        byteBuffer.put("w are you?\n".getBytes());
        split(byteBuffer);
    }

    private static void split(ByteBuffer source) {
        //切换读模式
        source.flip();
        //循环所有接受到的字节数据
        for (int i = 0; i < source.limit(); i++) {
            //判断是否到达一个数据包的结尾，source.get(i)只是拿到某个角标上的数据，不会移动position
            if (source.get(i)=='\n'){
                //判断这个数据包的长度
                int len = i+1-source.position();
                //分配一个和数据包长度一样的ByteBuffer
                ByteBuffer target = ByteBuffer.allocate(len);
                for (int index = 0; index < len; index++) {
                    target.put(source.get());
                }
                System.out.print(new String(target.array()));
            }
        }
        //压缩数据包，读过的数据会被清除，没有读过的会被保留，和clear不同
        source.compact();
    }

}
